import datetime

import arrow
import django_mongoengine_filter
from dateutil.relativedelta import relativedelta
from rest_framework_mongoengine import serializers

from models.audit_log import AuditLog
from wass.display import MODULE_NAME_DICT


class LogFilter(django_mongoengine_filter.FilterSet):
    """日志查询过滤器"""

    property_name = django_mongoengine_filter.MethodFilter(action="contain_filter")
    start_date = django_mongoengine_filter.MethodFilter(action="start_date_filter")
    end_date = django_mongoengine_filter.MethodFilter(action="end_date_filter")
    group = django_mongoengine_filter.MethodFilter(action="group_filter")
    operator = django_mongoengine_filter.MethodFilter(action="operator_filter")
    ip = django_mongoengine_filter.MethodFilter(action="ip_filter")
    module = django_mongoengine_filter.MethodFilter(action="module_filter")
    type = django_mongoengine_filter.MethodFilter(action="type_filter")

    class Meta:
        model = AuditLog
        fields = [
            'module',
            'type',
            "action",
            "property_name",
            "start_date",
            "end_date",
            'group',
            'operator',
            'ip',
        ]

    def contain_filter(self, queryset, name, value):
        query_kwargs = {f"{name}__contains": value}
        if value:
            return queryset.filter(**query_kwargs)
        return queryset

    def start_date_filter(self, queryset, name, value):
        """起始日期"""
        now_arrow_time = arrow.utcnow()
        default_from_date = now_arrow_time.shift(months=-6).datetime
        if value:
            try:
                from_date = arrow.get(value).datetime
            except ValueError:
                raise serializers.serializers.ValidationError("时间格式错误")
            if from_date < default_from_date:
                raise serializers.serializers.ValidationError("时间范围不合法,只能查询最近半年数据")
            return queryset.filter(time__gte=int(from_date.timestamp()))
        else:
            # 默认查询近半年数据
            return queryset.filter(time__gte=int(default_from_date.timestamp()))

    def end_date_filter(self, queryset, name, value):
        """截止日期(包含)"""
        if not value:
            value = datetime.datetime.now().strftime("%Y-%m-%d")
        try:
            to_date_time = arrow.get(value).datetime
        except ValueError:
            raise serializers.serializers.ValidationError("时间格式错误")
        return queryset.filter(time__lte=to_date_time.timestamp())

    @staticmethod
    def group_filter(queryset, name, value):
        return queryset.filter(group__in=[value])

    @staticmethod
    def ip_filter(queryset, name, value):
        if not value:
            return queryset

        return queryset.filter(ip__contains=value)

    @staticmethod
    def operator_filter(queryset, name, value):
        if not value:
            return queryset

        return queryset.filter(operator__contains=value)

    @staticmethod
    def module_filter(queryset, name, value):
        if not value:
            return queryset

        return queryset.filter(module=value)

    @staticmethod
    def type_filter(queryset, name, value):
        if not value:
            return queryset

        return queryset.filter(type=value)
